package com.qjq.glasses_shopping.service.impl;


import com.qjq.glasses_shopping.mapper.CartGoodsMapper;
import com.qjq.glasses_shopping.mapper.OrdersMapper;
import com.qjq.glasses_shopping.pojo.CartGoods;
import com.qjq.glasses_shopping.pojo.Orders;
import com.qjq.glasses_shopping.service.OrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;


import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class OrdersServiceImpl implements OrdersService {
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private CartGoodsMapper cartGoodsMapper;
    @Autowired
    private RedisTemplate redisTemplate;




    @Override
    public Orders add(Orders orders) {
        // 订单状态未付款
        if (orders.getStatus() == null){
            orders.setStatus(1);
        }
        // 订单创建时间
        orders.setCreateTime(new Date());
        // 计算订单价格
        List<CartGoods> cartGoods = orders.getCartGoods();
        BigDecimal sum = BigDecimal.ZERO;
        for (CartGoods cartGood : cartGoods) {
            BigDecimal num = new BigDecimal(cartGood.getNum()); // 数量
            BigDecimal price = cartGood.getPrice(); // 单价
            BigDecimal multiply = num.multiply(price);
            sum = sum.add(multiply);
        }
        orders.setPayment(sum);
        // 保存订单
        ordersMapper.insert(orders);
        // 将订单商品（购物车商品）保存到数据库中
        for (CartGoods cartGood : cartGoods) {
            cartGood.setOrderId(orders.getId());
            cartGoodsMapper.insert(cartGood);
        }

        // 3.将订单数据保存到Redis中
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // 设置订单1分钟过期
        redisTemplate.opsForValue().set(orders.getId(), orders, 1, TimeUnit.MINUTES);
        /**
         * 给订单创建副本，副本的过期时间长于原订单
         * redis过期后触发过期事件时，redis的数据已经过期，此时只能拿到key，拿不到value
         * 而过期事件需要回退商品库存，必须拿到value即订单详情，才能拿到商品数据，进行回退操作
         * 我们保存一个订单副本，过期时间长于原订单，我们就可以通过副本拿到订单数据
         */
        redisTemplate.opsForValue().set(orders.getId() + "_copy1", orders, 2, TimeUnit.MINUTES);
        System.out.println("下单成功，订单号:"+orders.getId());
        System.out.println("订单状态:"+orders.getStatus());
        return orders;
    }




    @Override
    public void update(Orders orders) {
        ordersMapper.updateById(orders);
    }

    @Override
    public Orders findById(String id) {
        return ordersMapper.findById(id);
    }

    @Override
    public List<Orders> findUserOrders(Long userId, Integer status) {
        List<Orders> ordersList = ordersMapper.findOrdersByUserIdAndStatus(userId, status);
        return ordersList;
    }
}
